<template>
  <div class="login-scan-container">
    <div class="qrcode-wrap">
      <div class="lock-mask" v-if="lockQrcode">
        <div class="refresh-icon" v-if="refreshState" @click="getQrcode">
          <el-icon>
            <ele-Refresh/>
          </el-icon>
        </div>
        <div class="scanned" v-if="scannedState" @click="getQrcode">
          <el-icon>
            <ele-Check/>
          </el-icon>
        </div>
        <div class="tip">{{ stateTip }}</div>
      </div>
      <div ref="qrcodeRef"></div>
    </div>
    <div class="font12 mt20 login-msg">{{ $t('message.scan.text') }}</div>
  </div>
</template>

<script lang="ts">
import {ref, defineComponent, onMounted, reactive, computed, getCurrentInstance, toRefs} from 'vue';
import QRCode from 'qrcodejs2-fixes';
import {checkQrcodeState, generateQrcode} from "/@/api/login";
import {Session} from "/@/utils/storage";
import {initFrontEndControlRoutes, initSystemCardWidgets} from "/@/router/frontEnd";
import {initBackEndControlRoutes} from "/@/router/backEnd";
import {useI18n} from 'vue-i18n';
import {useThemeConfig} from "/@/stores/themeConfig";
import {storeToRefs} from "pinia";
import {ElMessage} from "element-plus";
import {NextLoading} from "/@/utils/loading";
import {useRoute, useRouter} from "vue-router";
import {formatAxis} from "/@/utils/formatTime";

export default defineComponent({
  name: 'loginScan',
  setup(props, {emit}) {
    const {t} = useI18n();
    const {proxy} = <any>getCurrentInstance();
    const storesThemeConfig = useThemeConfig();
    const {themeConfig} = storeToRefs(storesThemeConfig);
    const route = useRoute();
    const router = useRouter();
    const state = reactive({
      ticketKey: '',
      interval: '',
      lockQrcode: false,
      refreshState: false,
      scannedState: false,
      stateTip: ''
    });
    const qrcodeRef = ref<HTMLElement | null>(null);
    // 初始化生成二维码
    const initQrcode = () => {
      (qrcodeRef.value as HTMLElement).innerHTML = '';
      if (state.ticketKey == '') {
        alert(state.ticketKey)
      } else {
        new QRCode(qrcodeRef.value, {
          text: state.ticketKey,
          width: 200,
          height: 200,
          colorDark: '#000000',
          colorLight: 'transparent',
        });
        // 开启轮询
        checkScanState();
      }
    };
    const checkScanState = async () => {
      state.interval = setInterval(async () => {
        checkQrcodeState({ticketKey: state.ticketKey}).then(res => {
          const _data = res.data;
          switch (_data.code) {
            case 9000:
              // 未扫码
              state.lockQrcode = false;
              state.refreshState = false;
              state.stateTip = '';
              state.scannedState = false;
              break;
            case 9002:
              // 扫码成功
              state.lockQrcode = true;
              state.stateTip = _data.msg;
              state.scannedState = true;
              break;
            case 9003:
            case 9004:
            case 9005:
              // 二维码异常
              state.lockQrcode = true;
              state.stateTip = _data.msg;
              state.refreshState = true;
              state.scannedState = false;
              clearInterval(state.interval)
              break;
            case 10000:
              // 成功授权
              clearInterval(state.interval)
              state.lockQrcode = true;
              state.stateTip = _data.msg;
              state.refreshState = false;
              // 写数据
              const userInfo = _data.ext.user
              userInfo.avatar = proxy.getUpFileUrl(userInfo.avatar)
              // 存储 token 到浏览器缓存
              Session.set('token', _data.ext.token);
              // 存储用户信息到浏览器缓存
              Session.set('userInfo', userInfo);
              // 设置用户菜单
              Session.set('userMenu', _data.ext.menus)
              // 设置按钮权限
              Session.set('permissions', _data.ext.permissions)
              // 模拟数据，对接接口时，记得删除多余代码及对应依赖的引入。用于 `/src/stores/userInfo.ts` 中不同用户登录判断（模拟数据）
              // Cookies.set('username', state.ruleForm.username);
              // get widgets
              if (!themeConfig.value.isRequestRoutes) {
                // 前端控制路由，2、请注意执行顺序
                initFrontEndControlRoutes();
                signInSuccess();
              } else {
                initSystemCardWidgets();
                // 模拟后端控制路由，isRequestRoutes 为 true，则开启后端控制路由
                // 添加完动态路由，再进行 router 跳转，否则可能报错 No match found for location with path "/"
                initBackEndControlRoutes();
                // 执行完 initBackEndControlRoutes，再执行 signInSuccess
                signInSuccess();
              }
              break;
          }
        })
      }, 2500)
    };
    const currentTime = computed(() => {
      return formatAxis(new Date());
    });
    const getQrcode = () => {
      state.lockQrcode = false;
      state.refreshState = false;
      state.scannedState = false;
      state.stateTip = '';
      generateQrcode({type: 'login'}).then(res => {
        state.ticketKey = res.data.ticketKey
        initQrcode();
      });
    }
    const signInSuccess = () => {
      // 初始化登录成功时间问候语
      let currentTimeInfo = currentTime.value;
      // 登录成功，跳到转首页
      // 如果是复制粘贴的路径，非首页/登录页，那么登录成功后重定向到对应的路径中
      if (route.query?.redirect) {
        router.push({
          path: <string>route.query?.redirect,
          query: Object.keys(<string>route.query?.params).length > 0 ? JSON.parse(<string>route.query?.params) : '',
        });
      } else {
        router.push('/');
      }
      // 登录成功提示
      // 关闭 loading
      // state.loading.signIn = true;
      const signInText = t('message.signInText');
      ElMessage.success(`${currentTimeInfo}，${signInText}`);
      // 添加 loading，防止第一次进入界面时出现短暂空白
      NextLoading.start();
    };
    // 页面加载时
    onMounted(() => {
      getQrcode();
    });
    return {
      qrcodeRef,
      getQrcode,
      ...toRefs(state)
    };
  },
});
</script>

<style scoped lang="scss">
.login-scan-animation {
  opacity: 0;
  animation-name: error-num;
  animation-duration: 0.5s;
  animation-fill-mode: forwards;
}

.login-scan-container {
  padding: 20px;
  display: flex;
  flex-direction: column;
  text-align: center;
  @extend .login-scan-animation;
  animation-delay: 0.1s;
  align-items: center;

  .qrcode-wrap {
    padding: 20px;
    background-color: #ffffff;
    border-radius: 20px;
    width: 240px;
    height: 240px;
    position: relative;

    .lock-mask {
      position: absolute;
      background-color: #000000;
      opacity: 0.8;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      display: flex;
      border-radius: 20px;
      align-items: center;
      flex-direction: column;
      flex-wrap: nowrap;
      align-content: center;
      justify-content: center;

      .el-icon {
        font-size: 40px;
        color: #ffffff;
        margin-bottom: 10px;
      }

      .tip {
        color: #ffffff;
      }
    }
  }

  :deep(img) {
    margin: auto;
  }

  .login-msg {
    color: var(--el-text-color-placeholder);
    @extend .login-scan-animation;
    animation-delay: 0.2s;
  }
}
</style>
